<?php
namespace app\task\controller;

use hema\wechat\WxBizMsgCrypt;
use hema\wechat\Driver;
use app\task\model\Applet as AppletModel;
use app\task\model\Wechat as WechatModel;
use app\task\model\Keyword as KeywordModel;
use app\task\model\User as UserModel;
use app\task\model\Setting;
use app\task\model\AppletTpl as AppletTplModel;
use app\task\model\AppletName as AppletNameModel;
use app\task\model\WechatBatchSend as WechatBatchSendModel;
use think\facade\Session;
/**
 * 第三方平台与微信通讯接口
 */
class Wechat extends \app\BaseController
{
	protected $wechat;    //公众号
    /**
     * 异步通知处理
     */
    public function callback(string $appid = '')
    {
    	$this->wechat = WechatModel::getWechat(['app_id' => $appid]);
		// 接收公众号平台发送的消息
		$nonce = empty ( $_GET ['nonce'] ) ?"" : trim ( $_GET ['nonce'] );
		$signature = empty ( $_GET['signature'] ) ? "" : trim ( $_GET ['signature'] );
		$timeStamp = empty ( $_GET ['timestamp']) ? "" : trim ( $_GET ['timestamp'] );
		$msg_signature = empty ( $_GET['msg_signature'] ) ? "" : trim ( $_GET ['msg_signature'] );
		$encryptMsg = file_get_contents ('php://input' );

        //创建解密类
		$pc = new WxBizMsgCrypt();
		$msg = '';		
		$errCode = $pc->decryptMsg($msg_signature, $timeStamp, $nonce, $encryptMsg, $msg);	
		if($errCode == 0){
			$data = _xml_to_arr($msg);	//XML转换为数组
			//write_log($data, __DIR__);
			//*********************************接收事件推送*****************************************
			if($data['MsgType']=='event'){
				//用户未关注时，进行关注后的事件推送
				if($data['Event']=='subscribe'){
					//是否设置了关注回复
					if($subscribe = Setting::getItem('subscribe',$this->wechat['applet_id'])){
						$this->replyMsg($subscribe,$data);//回复信息
					} 
					//获取粉丝资料
					$wx = new Driver;
					if($wechat_user = $wx->getWechatUserInfo($data['FromUserName'],$this->wechat['applet_id'])){
						//用户操作
						$model = new UserModel;
						$user_name = $model->subscribe($wechat_user,$this->wechat['applet_id']);
						if($this->wechat['applet_id'] == 0){
							$helper = Setting::getItem('foodhelp',0);
							$wx->sendServiceMsg([
								'type' => 'text',
								'content' => '请妥善保管您的账号和密码~
如忘记回复“找回账号”找回~
账号：' . $user_name . '
密码：123456' . '
<a href="http://www.qq.com" data-miniprogram-appid="'.$helper['app_id'].'" data-miniprogram-path="pages/index/index">点此跳转商家助手小程序 >></a>'
							],$data['FromUserName'],$this->wechat['applet_id']);
						}
					}else{
						//返回文本提醒
						$wx->sendServiceMsg([
							'type' => 'text',
							'content' => '公众号未关联开放平台，会影响后续使用！'
						],$data['FromUserName'],$this->wechat['applet_id']);
					}
					die('success');
				}
				
				//用户已关注时扫码进入事件推送
				if($data['Event']=='SCAN'){
					die('success');
				}
				//取消关注事件
				if($data['Event']=='unsubscribe'){
					if($model = UserModel::getUser(['open_id' => $data['FromUserName']])){
						$model->unSubscribe();
					}
					die('success');
				}
				
				//扫描带参数二维码事件 - 用户未关注时，进行关注后的事件推送
				if($data['Event']=='subscribe' AND isset($data['EventKey'])){
					die('success');
				}
				
				//扫描带参数二维码事件 - 用户已关注时的事件推送
				if($data['Event']=='SCAN'){
					die('success');
				}
				
				//上报地理位置事件
				if($data['Event']=='LOCATION'){
					die('success');
				}
				
				//自定义菜单事件 - 点击菜单拉取消息时的事件推送
				if($data['Event']=='CLICK'){
					//$this->textMsg($data);
					die('success');
				}
				
				//自定义菜单事件 - 点击菜单跳转链接时的事件推送
				if($data['Event']=='VIEW'){
					die('success');
				}
				//添加附近门店类目审核回调
				if($data['Event']=='nearby_category_audit_info'){
					//$this->nearby_category_audit_info($data);
					die('success');
				}
				
				//添加附近小程序地点审核回调
				if($data['Event']=='add_nearby_poi_audit_info'){
					write_log('添加附近小程序地点审核回调',__DIR__);
					die('success');
				}
				
				//群发任务回调事件推送
				if($data['Event']=='MASSSENDJOBFINISH'){
					$msg = WechatBatchSendModel::getSend(['msg_id' => $data['MsgID']]);
					$msg->backEdit($data);
					die('success');
				}
				//代码审核成功结果推送
				if($data['Event'] == 'weapp_audit_success'){
					//获取商户数据
					if($applet = AppletModel::getApplet(['user_name' => $data['ToUserName']])){ 
						if($tpl = AppletTplModel::getNew($applet['applet_id'])){
							//发布小程序模板
                            $wx = new Driver;
                            $result = $wx->release($applet['applet_id']);
                            if($result['errcode'] == 0){
                                $tpl->save(['status' => 2]); //已上线
                                $applet->save(['applet_tpl_id' => $tpl['applet_tpl_id']]);
                            }else{
                            	$tpl->save(['status' => 3]);//待发布
                            }
						}
					}
					die('success');
				}
				//代码审核失败结果推送
                if($data['Event'] == 'weapp_audit_fail'){
                    //获取商户数据
					if($applet = AppletModel::getApplet(['user_name' => $data['ToUserName']])){ 
						if($tpl = AppletTplModel::getNew($applet['applet_id'])){
							$tpl->save(['status' => 1,'reason' => $data['Reason']]);//被拒绝
						}
					}
                    die('success');
                }
                //代码审核延后推送
                if($data['Event'] == 'weapp_audit_delay'){
                    //获取商户数据
					if($applet = AppletModel::getApplet(['user_name' => $data['ToUserName']])){ 
						if($tpl = AppletTplModel::getNew($applet['applet_id'])){
							$tpl->save(['status' => 4]);//审核延后
						}
					}
                    die('success');
                }
                //名称审核结果事件推送
                if($data['Event'] == 'wxa_nickname_audit'){
                    if($applet = AppletModel::getApplet([
						'user_name' => $data['ToUserName']
					])){ 
                        if($name = AppletNameModel::getAppletName(['nick_name' => $data['nickname'],'applet_id' => $applet['applet_id'],'status' => 0])){
                            //成功
                            if($data['ret']==3){
                                $name->save(['status' => 1]);
                                $applet->save(['app_name' => $data['nickname']]);
                            }
                            //失败
                            if($data['ret']==2){
                                $name->save(['status' => 2,'reason' => $data['reason']]);
                                $applet->save(['app_name' => $data['nickname'] . '->被拒绝：'.$data['reason']]);
                            }
                        }
                    }
                    die('success');
                }
			}
			//*********************************接收普通消息*****************************************
			//接收普通消息 - 文本消息
			if($data['MsgType']=='text'){
				$this->textMsg($data);//文本消息处理
				die('success');
			}
			
			//接收普通消息 - 图片消息
			if($data['MsgType']=='image'){
				//发什么回什么
				echo $this->msgTpl([
					'ToUserName' => $data['FromUserName'],
					'FromUserName' => $data['ToUserName'],
					'MsgType' => $data['MsgType'],
					'MediaId' => $data['MediaId']
				]);
				die('success');
			}
			
			//接收普通消息 - 语音消息
			if($data['MsgType']=='voice'){
				//发什么回什么
				echo $this->msgTpl([
					'ToUserName' => $data['FromUserName'],
					'FromUserName' => $data['ToUserName'],
					'MsgType' => $data['MsgType'],
					'MediaId' => $data['MediaId']
				]);
				die('success');
			}
			
			//接收普通消息 - 视频消息
			if($data['MsgType']=='video'){
				//发什么回什么
				echo $this->msgTpl([
					'ToUserName' => $data['FromUserName'],
					'FromUserName' => $data['ToUserName'],
					'MsgType' => 'text',
					'Content' => '我不看，太低俗~'
				]);
				die('success');
			}
			
			//接收普通消息 - 小视频消息
			if($data['MsgType']=='shortvideo'){
				die('success');
			}
			
			//接收普通消息 - 地理位置消息
			if($data['MsgType']=='location'){
				die('success');
			}
			
			//接收普通消息 - 链接消息
			if($data['MsgType']=='link'){
				die('success');
			}
			die('success');
		}else{
			write_log('Wechat 解密失败 - 错误代码：'.$errCode, __DIR__);
		}
    }
	
	/**
     * 附近门店类目回调处理
    
	private function nearby_category_audit_info($data)
	{
		$model = NearbyCategoryModel::getDetail(['audit_id' => $data['audit_id']]);
		$model->edit($data);
	}
	*/
	/**
     * 添加附近展示地点回调处理
    */
	private function add_nearby_poi_audit_info($data)
	{
		$model = NearbyModel::getDetail(['audit_id' => $data['audit_id']]);
		$model->edit($data);
	}
	
	/**
     * 处理文本消息
    */
	private function textMsg($data)
	{
		//判断是否来自公众号菜单
		if(isset($data['EventKey'])){
			$data['Content'] = $data['EventKey'];
			$data['MsgType'] = 'text';
		}
		//是否设置了关键字回复
		switch($data['Content']){
			case 'id':
				echo $this->msgTpl([
						'ToUserName' => $data['FromUserName'],
						'FromUserName' => $data['ToUserName'],
						'MsgType' => 'text',
						'Content' => $data['FromUserName']
					]);
				break;
			case '找回账号':
				if($this->wechat['applet_id'] == 0){
					//获取用户信息ID
					if($model = UserModel::getUser(['open_id' => $data['FromUserName']])){
						if($model->retrieve()){
							echo $this->msgTpl([
								'ToUserName' => $data['FromUserName'],
								'FromUserName' => $data['ToUserName'],
								'MsgType' => 'text',
								'Content' => '恭喜：成功找回账号~
提醒：每次找回都要重置密码~
您的账号：' . $model['user_name'] . '
您的密码：123456'
						]);	
					}			
				}else{
					//返回文本提醒
					echo $this->msgTpl([
						'ToUserName' => $data['FromUserName'],
						'FromUserName' => $data['ToUserName'],
						'MsgType' => 'text',
						'Content' => '账号异常~
请取消关注该公众号后，在重新关注后进行操作。'
					]);
				}
				}
				break;
			default:
				if($values = KeywordModel::getKeys($data['Content'],$this->wechat['applet_id'])){
					$this->replyMsg($values,$data);//回复信息
				}else{
					if($values = KeywordModel::getKeys('*',$this->wechat['applet_id'])){
						$this->replyMsg($values,$data);//回复信息
					}else{
						//没有，发什么回什么
						echo $this->msgTpl([
							'ToUserName' => $data['FromUserName'],
							'FromUserName' => $data['ToUserName'],
							'MsgType' => $data['MsgType'],
							'Content' => $data['Content']
						]);
					}
				}
		}
	}
	
	/**
     * 回复消息
    */
	private function replyMsg($msg,$data)
	{
		//是否开启
		if($msg['is_open']==1){
			//文字消息
			if($msg['type']=='text'){
				echo $this->msgTpl([
					'ToUserName' => $data['FromUserName'],
					'FromUserName' => $data['ToUserName'],
					'MsgType' => 'text',
					'Content' => $msg['content']['description']
				]);
			}			
			//图片消息
			if($msg['type']=='image'){
				echo $this->msgTpl([
				  'ToUserName' => $data['FromUserName'],
				  'FromUserName' => $data['ToUserName'],
				  'MsgType' => 'image',
				  'MediaId' => $msg['content']['media_id']
				]);
			}
			//语音消息
			if($msg['type']=='voice'){
				echo $this->msgTpl([
				  'ToUserName' => $data['FromUserName'],
				  'FromUserName' => $data['ToUserName'],
				  'MsgType' => 'voice',
				  'MediaId' => $msg['content']['media_id']
				]);
			}
			//视频消息
			if($msg['type']=='video'){
				echo $this->msgTpl([
				  'ToUserName' => $data['FromUserName'],
				  'FromUserName' => $data['ToUserName'],
				  'MsgType' => 'video',
				  'Title' => $msg['content']['title'],
				  'Description' => $msg['content']['description'],
				  'MediaId' => $msg['content']['media_id']
				]);	
			}
			//音乐消息
			if($msg['type']=='music'){
				echo $this->msgTpl([
				  'ToUserName' => $data['FromUserName'],
				  'FromUserName' => $data['ToUserName'],
				  'MsgType' => 'music',
				  'Title' => $msg['content']['title'],
				  'Description' => $msg['content']['description'],
				  'MusicUrl' => $msg['content']['url'],
				  'HQMusicUrl' => $msg['content']['hurl'],
				  'ThumbMediaId' => $msg['content']['media_id']
				]);
			}
			//图文消息
			if($msg['type']=='news'){
				echo $this->msgTpl([
				  'ToUserName' => $data['FromUserName'],
				  'FromUserName' => $data['ToUserName'],
				  'MsgType' => 'news',
				  'Articles' => [
				  	'title' => $msg['content']['title'],
				  	'description' => $msg['content']['description'],
				  	'picurl' => $msg['content']['picurl'],
				  	'url' => $msg['content']['url']
				  ]
				]);
			}
		}
	}
	
	/**
     * 将array转为xml
    */
	private function msgTpl($arr)
	{
		$xml ="<xml><ToUserName><![CDATA[" . $arr['ToUserName'] . "]]></ToUserName>";
		$xml .="<FromUserName><![CDATA[" . $arr['FromUserName'] . "]]></FromUserName>";
		$xml .="<CreateTime>" . time() . "</CreateTime>";
		$xml .="<MsgType><![CDATA[" . $arr['MsgType'] . "]]></MsgType>";
		switch($arr['MsgType']){
			case "text":
				$xml .="<Content><![CDATA[" . $arr['Content'] . "]]></Content>";
				break;
			case "image":
				$xml .= "<Image><MediaId><![CDATA[" . $arr['MediaId'] . "]]></MediaId></Image>";
				break;
			case "voice":
				$xml .= "<Voice><MediaId><![CDATA[" . $arr['MediaId'] . "]]></MediaId></Voice>";
				break;
			case "video":
				$xml .= "<Video><MediaId><![CDATA[" . $arr['MediaId'] . "]]></MediaId><Title><![CDATA[" . $arr['Title'] . "]]></Title><Description><![CDATA[" . $arr['Description'] . "]]></Description></Video>";
				break;
			case "music":
				$xml .= "<Music><Title><![CDATA[" . $arr['Title'] . "]]></Title><Description><![CDATA[" . $arr['Description'] . "]]></Description><MusicUrl><![CDATA[" . $arr['MusicUrl'] . "]]></MusicUrl><HQMusicUrl><![CDATA[" . $arr['HQMusicUrl'] . "]]></HQMusicUrl><ThumbMediaId><![CDATA[" . $arr['ThumbMediaId'] . "]]></ThumbMediaId></Music>";
				break;
			case "news":
				$xml .= "<ArticleCount>1</ArticleCount><Articles>";
				$xml .= "<item><Title><![CDATA[". $arr['Articles']['title'] ."]]></Title><Description><![CDATA[". $arr['Articles']['description'] ."]]></Description><PicUrl><![CDATA[". $arr['Articles']['picurl'] ."]]></PicUrl><Url><![CDATA[". $arr['Articles']['url'] ."]]></Url></item>";
				$xml .= "</Articles>";
				break;
		}
		$xml .= "</xml>";
		return $xml;
	}
}
